package cn.com.bluemoon.daps.model.core.file.transformer;

import cn.com.bluemoon.daps.common.domain.ResultBean;
import cn.com.bluemoon.daps.common.toolkit.BmAssetUtils;
import cn.com.bluemoon.daps.model.core.file.TableInfoDto;
import cn.com.bluemoon.daps.model.entity.*;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 转换为入库结构
 *
 * @author Jarod.Kong
 * @date 2021/3/11 14:46
 */
public class ToDaoDataTransformer implements Transformer<TableInfoDto, ImportEntryTableDto> {
    private DapDataModel dataModel;

    public ToDaoDataTransformer(DapDataModel dataModel) {
        this.dataModel = dataModel;
        checkModel0();
    }

    private void checkModel0() {
        BmAssetUtils.isTrue(dataModel != null, "指定模型信息");
    }

    public void setModel(DapDataModel dataModel) {
        this.dataModel = dataModel;
    }

    public DapDataModel getDataModel() {
        return dataModel;
    }

    /**
     * 把通过解析器+检查器后的数据，进行转换
     * {@link TableInfoDto} to {@link ImportEntryTableDto}
     *  类似DDD的转换方式
     *
     * @param info x
     * @return x
     */
    @Override
    public ImportEntryTableDto transform(TableInfoDto info) {
        checkModel0();

        final String modelId = dataModel.getId();
        final String dataSourceId = dataModel.getDataSourceId();
        final String tableId = IdWorker.getIdStr();
        // transform
        ResultBean<DapDataModelTable> tableRb = info.getTableData().convertToModel(dataModel);
        BmAssetUtils.isTrue(tableRb.isOk(), tableRb.getMsg());
        DapDataModelTable table = tableRb.getContent();
        {
            table.setDataModelId(modelId);
            table.setDataSourceId(dataSourceId);
            table.setId(tableId);
        }

        final Function<DapDataModelTableField, DapDataModelTableField> fieldFunc = f -> {
            f.setId(IdWorker.getIdStr());
            f.setModelTableId(tableId);
            f.setDataModelId(modelId);
            return f;
        };
        final Function<DapDataModelSubordinateKey, DapDataModelSubordinateKey> indexFunc = f -> {
            f.setId(IdWorker.getIdStr());
            f.setModelTableId(tableId);
            f.setDataModelId(modelId);
            return f;
        };
        final Function<DapDataModelTablePartition, DapDataModelTablePartition> partitionFunc = f -> {
            f.setId(IdWorker.getIdStr());
            f.setModelTableId(tableId);
            f.setDataModelId(modelId);
            return f;
        };
        List<DapDataModelTableField> fields = info.getFieldDatas()
                .stream()
                .map(d -> {
                    return d.convertToModel(dataModel).getContent();
                })
                .map(fieldFunc).collect(Collectors.toList());
        final Map<String, String> fNameAndFids = fields.stream().collect(Collectors.toMap(
                DapDataModelTableField::getFieldName,
                DapDataModelTableField::getId, (a, b) -> b));
        List<DapDataModelSubordinateKey> indexes = info.getIndexDatas().stream()
                .map(d -> {
                    d.setFieldNameAndIds(fNameAndFids);
                    return d.convertToModel(dataModel).getContent();
                })
                .map(indexFunc).collect(Collectors.toList());
        List<DapDataModelTablePartition> partitions = info.getPartitionDatas().stream()
                .map(d -> {
                    return d.convertToModel(dataModel).getContent();
                })
                .map(partitionFunc)
                .collect(Collectors.toList());
        ImportEntryTableDto build = ImportEntryTableDto.builder().table(table).fields(fields).indexes(indexes)
                .partitions(partitions).build();
        return build;
    }

}
